DEFine FuNction

Syntax: DEFine FuNction name[$ | %] [(item {,item} )]
Location: QL ROM

The syntax of the SuperBASIC function can take two forms:

DEFine FuNction name[$ | %] [(item {,item})]: statement {:statement}:
RETurn value: END DEFine
or

DEFine FuNction name[$ | %] [(item {,item} )]
{LOCal var {,var} }
{statements}
RETurn value
END DEFine [name]

To call the DEFine FuNction, you merely need to include its name in an expression. If however any parameters are listed in the definition, you will need to pass the same number of parameters in brackets after the name of the FuNction, separated by any valid SuperBASIC separator {ie. comma (,), semicolon (;), backslash (\), exclamation mark (!) or TO }.

You can also place a hash (#) before the parameters if you so wish to indicate that it is a channel number. If not enough parameters are supplied, the program will report 'Error in Expression' when the missing parameter is used, except under SMS where the missing parameters are treated as unset variables and will therefore have the value 0 (if a numeric variable) or else contain an empty string (if a string variable).

If however, too many parameters are passed, the extra parameters are ignored.

Parameters are passed by reference which means that the list of items in the DEFine FuNction statement are deemed LOCal to that definition - this means that any previous values of the items are stored whilst the definition block is active. What is more, the type of each item does not actually matter - they assume the type of the passed parameter.

Note:
The name of the FuNction must end with the correct variable type, ie. $ if a string is to be returned, or % if an integer is to be returned.

One of the results of passing variables by reference is that if the item is altered within the definition block, if a variable is passed as a parameter, the variable itself will also be altered.

This can be avoided by either assigning the item to a temporary variable and then using the temporary variable instead (see the example below), or by passing the variable as an expression, by placing it inside brackets.

Having passed the necessary parameters to the Function, you can then use each item inside the definition block as normal. 

NOTE:
A FuNction must return a value under all circumstances. If the END DEFine is reached without a value having been returned then SuperBASIC will report an 'error in expression' (-17), specifying the error as having occured at the line containing the END DEFine.  Under SMS the error 'RETurn not in PROCedure or FuNction' will be reported instead.

On pre MG ROMs, any more than nine parameters may upset the program, corrupting it by replacing names with PRINT towards the end of a program.

Although a sub-set of a simple string is an expression and therefore will not be altered within a function, a sub-set of a DIMensioned string is not treated as an expression and will therefore be altered!!

WARNING:
On most ROMs (at least on JM, MGx, AH and Minerva up to v1.97), a single line recursive FuNction will not respond to the break key. For example:   

10 DEFine FuNction Root(a): a=2^Root(a)

This is fixed on SMS v2.59+.

CROSS-REFERENCE:
RETurn allows you to return the result of the Function.
DEFine PROCedure is very similar.
LOCal allows you to assign temporary variables with the same name as variables used outside the definition block. 
PARUSE and PARTYP allow you to examine the type of the parameters which are passed to the definition block.
